package com.kerust.utils

import android.annotation.SuppressLint
import android.content.Context
import android.net.wifi.WifiManager
import android.os.Handler
import android.os.Message
import android.util.Log
import com.kerust.bean.BoardDevice
import com.kerust.interfaces.InternalFinderListener
import java.io.IOException
import java.net.InetAddress
import java.net.URI
import java.net.UnknownHostException
import java.util.*
import javax.jmdns.JmDNS
import javax.jmdns.ServiceEvent
import javax.jmdns.ServiceListener

/**
 * Created by mr.kong on 2017/9/25.
 */
class FindBoardDevice private constructor() {
    private lateinit var jmDNS: JmDNS
    private lateinit var listener: ServiceListener
    private lateinit var wifi: WifiManager
    private lateinit var lock: WifiManager.MulticastLock
    private val type = "_kerust._tcp.local."
    private var mBoardDevice: MutableList<BoardDevice> = ArrayList()
    private lateinit var mListener: InternalFinderListener
    private val FIND_BOARD_DEVICE: Int = 100

    private val mHandler = object : Handler() {
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            if (msg.what == FIND_BOARD_DEVICE) {
                val obj = msg.obj
                mListener?.findResult(obj as List<BoardDevice>)
            }
        }
    }

    companion object {
        fun getInstance(): FindBoardDevice {
            return Inner.boardDeviceUtils
        }
    }

    private object Inner {
        val boardDeviceUtils = FindBoardDevice()
    }

    fun callFunctionInBackground(context: Context, mListener: InternalFinderListener) {
        this.mListener = mListener
        Thread(object : Runnable {
            @SuppressLint("WifiManagerLeak")
            override fun run() {
                wifi = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
                lock = wifi.createMulticastLock(javaClass.simpleName)
                lock.setReferenceCounted(true)
                try {
                    val localIpAddress = getLocalIpAddress(context)
                    lock.acquire()
                    jmDNS = JmDNS.create(localIpAddress)
                    listener = object : ServiceListener {
                        override fun serviceAdded(serviceEvent: ServiceEvent) {
                            jmDNS?.requestServiceInfo(serviceEvent.type,
                                    serviceEvent.name, 1)
                        }

                        override fun serviceRemoved(serviceEvent: ServiceEvent) {
                            Log.e("zhuangtai", "有服务断开" + "serviceRemoved")
                        }

                        override fun serviceResolved(serviceEvent: ServiceEvent) {
                            val name = serviceEvent.name
                            val deviceInfo = name.split("&")
                            val urLs = serviceEvent.info.urLs
                            val boardDevice = BoardDevice(deviceInfo[0], deviceInfo[1], URI(urLs[0]))
                            mBoardDevice.add(boardDevice)
                            mListener.findResult(mBoardDevice)
//                            val obtain = Message.obtain()
//                            obtain.what = FIND_BOARD_DEVICE
//                            obtain.obj = mBoardDevice
//                            mHandler.sendMessage(obtain)
                        }
                    }
                    jmDNS?.addServiceListener(type, listener)
                } catch (e: IOException) {
                    e.printStackTrace()
                    return
                }
            }
        }).start()
    }

    private fun getLocalIpAddress(context: Context): InetAddress {
        val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
        val connectionInfo = wifiManager.connectionInfo
        val ipAddress = connectionInfo.ipAddress
        var address: InetAddress? = null
        try {//ipAddress & 0xff | ipAddress
            address = InetAddress.getByName(String.format(Locale.ENGLISH, "%d.%d.%d.%d", ipAddress and 0xff,
                    ipAddress shr 8 and 0xff, ipAddress shr 16 and 0xff, ipAddress shr 24 and 0xff))
        } catch (e: UnknownHostException) {
            e.printStackTrace()
        }
        return address!!
    }

    /**
     * 释放资源 手动调用 在不使用搜索设备场景的时候
     */
    fun releasingResources() {
        if (jmDNS != null) {
            if (listener != null) {
                jmDNS?.removeServiceListener(type, listener)
            }
            jmDNS?.unregisterAllServices()
            try {
                jmDNS?.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }

        }
        lock.release()
    }

}